import logging
import os.path
import threading
import time

import cv2


class Images:

    @classmethod
    def crop_picture(cls, picture, x1=0, y1=72, x2=720, y2=1208, new=False):
        """
        图片裁剪
        :param picture: 需要裁剪的图片
        :param x1: 左
        :param y1: 上
        :param x2: 右
        :param y2: 下
        :param new: 是否需要另存
        :return: 不另存，则覆盖原图，否则保留原图，裁剪的后的图片另存
        """
        img = cv2.imread(picture)
        img = img[y1:y2, x1:x2]
        if new:
            pic_dir = os.path.dirname(picture)
            pic_name = os.path.basename(picture)
            name, extension = pic_name.split('.')
            new_pic = os.path.join(pic_dir, '{}_{}_{}_{}_{}.{}'.format(name, x1, y1, x2, y2, extension))
        else:
            new_pic = picture
        cv2.imwrite(new_pic, img)
        return new_pic

    @classmethod
    def compare_image_similarity(cls, image1, image2, threshold=0):
        # 将图像resize后，分离为RGB三个通道，再计算每个通道的相似值
        logging.info('{}是否存在？[{}]'.format(image1, os.path.exists(image1)))
        logging.info('{}是否存在？[{}]'.format(image2, os.path.exists(image2)))
        if not os.path.exists(image1) or not os.path.exists(image2):
            logging.info('文件缺失，相似度为0%')
            return 0
        image1 = cv2.imread(image1)
        image2 = cv2.imread(image2)
        sub_image1 = cv2.split(image1)
        sub_image2 = cv2.split(image2)
        sub_data = 0
        for im1, im2 in zip(sub_image1, sub_image2):
            sub_data += cls._calculate(im1, im2, threshold)
        sub_data = sub_data / 3
        logging.info('相似度：{}%'.format(sub_data * 100))
        return sub_data

    # 计算单通道的直方图的相似值
    @classmethod
    def _calculate(cl, image1, image2, threshold):
        hist1 = cv2.calcHist([image1], [0], None, [256], [0, 255])
        hist2 = cv2.calcHist([image2], [0], None, [256], [0, 255])
        # 计算直方图的重合度
        degree = 0
        for i in range(len(hist1)):
            h1 = hist1[i][0]
            h2 = hist2[i][0]

            if abs(h1 - h2) > threshold:
                degree = degree + (1 - abs(h1 - h2) / max(h1, h2))
            else:
                degree = degree + 1
        degree = degree / len(hist1)
        return degree

    @classmethod
    def is_image_in_image(cls, template_path, target_path, threshold=0.8):
        """
        使用模板匹配判断模板图像template_path是否在目标图像target_path中
        :param template_path: 模板图像路径
        :param target_path: 目标图像路径
        :param threshold: 匹配阈值（0 到 1 之间，值越大匹配越严格）
        :return: True 或 False
        """
        # 读取图像
        template = cv2.imread(template_path, cv2.IMREAD_GRAYSCALE)  # 灰度模式
        target = cv2.imread(target_path, cv2.IMREAD_GRAYSCALE)  # 灰度模式

        # 获取模板图像的尺寸
        try:
            if not template:
                return False
        except:
            pass

        # 使用模板匹配
        result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

        # 判断匹配度是否超过阈值
        if max_val >= threshold:
            logging.info(f"模板图像在目标图像中，匹配度: {max_val}")
            return True
        else:
            logging.info(f"模板图像不在目标图像中，匹配度: {max_val}")
            return False


class SnapshotThread(threading.Thread):
    def __init__(self, device):
        super().__init__()
        self.device = device
        self.stop_event = threading.Event()

    def run(self):
        i = 0
        self.stop_event.clear()
        while not self.stop_event.is_set():
            self.device.save_snapshot_to_local(f'step{i}.jpeg')
            time.sleep(3)
            i += 1

    def stop(self):
        self.stop_event.set()


class MatchRules:
    Equal = '完全相等'
    Contain = '包含'


class Direction:
    Left = 0
    Right = 1
    Up = 2
    Down = 3
